package org.chen.tomcat;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.*;

/**
 * socket连接处理器
 *
 * @author Chen
 * @since 2023/6/9 15:06
 */
public class SocketProcessor implements Runnable {

    private final Socket socket;

    private final HttpServlet httpServlet;

    public SocketProcessor(Socket socket, HttpServlet dispatcherServlet) {
        this.socket = socket;
        this.httpServlet = dispatcherServlet;
    }

    @Override
    public void run() {
        processSocket(socket);
    }

    private void processSocket(Socket socket) {
        InputStream inputStream;
        try {
            inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];
            int read = inputStream.read(bytes);
            //解析字节流,遇到一个空格就退出
            //初始化指针
            int pos = -1;
            int begin = -1, end = -1;
            //获取一共多少字段
            String str = new String(bytes,0,read);
            int size = str.split(" ").length;
            List<String> paramsList = new ArrayList<>();
            //遍历获取每个字段的值
            for (int i = 0; i < size; i++) {
                //获取每个空格之前的字符
                StringBuilder url = getUrl(bytes, ++pos, ++begin, ++end);
                //获取字符的长度
                int length = url.length();
                //移动指针位置，让下次循环从空格的下一个位置开始
                pos += length;
                begin += length;
                end += length;
                //打印每个字段的值
                paramsList.add(url.toString());
            }
            int paramsSize = paramsList.size();
            String method = "GET";
            String url = "/";
            String protocol = "HTTP/1.1";

            if (paramsSize >= 1) {
                method = paramsList.get(0);
            }
            if (paramsSize >= 2) {
                url = paramsList.get(1);
            }
            if (paramsSize >= 3) {
                protocol = paramsList.get(2);
            }

            //这里实现LinkedHashMap是为了保证参数的顺序
            Map<String, String[]> parameterMap = new LinkedHashMap<>();
            //解析参数
            if (url.contains("?")) {
                String[] split = url.split("\\?");
                url = split[0];
                String[] param = split[1].split("&");
                for (String s : param) {
                    String[] split1 = s.split("=");
                    parameterMap.put(split1[0], new String[]{split1[1]});
                }
            }
            Request request = new Request(method, url, parameterMap, protocol, socket);
            Response response = new Response(request);
            //匹配Servlet、doGet
            httpServlet.service(request, response);
            response.complete();
        } catch (IOException | ServletException e) {
            throw new RuntimeException(e);
        }
    }

    private static StringBuilder getUrl(byte[] bytes, int pos, int begin, int end) {

        for (; pos < bytes.length; pos++, end++) {
            if (bytes[pos] == ' ') {
                break;
            }
        }
        //组合空格之前的字节流，转换成字符串
        StringBuilder url = new StringBuilder();
        for (; begin < end; begin++) {
            url.append((char) bytes[begin]);
        }
        return url;
    }
}
